# -*- coding:utf-8 -*-
import sys
import os
import binascii
import struct
import re
import json
import traceback
import datetime
import time
import logging.config
import logging
import configparser
import logging.handlers
logging.config.fileConfig('./cfg/debug.conf')
'''
测试
版本:v1.0.0

'''

u8_lit = struct.Struct('B')
s8_lit = struct.Struct('b')
u16_lit = struct.Struct('<H')
s16_lit = struct.Struct('<h')
u32_lit = struct.Struct('<I')
s32_lit = struct.Struct('<i')
u64_lit = struct.Struct('<Q')
s64_lit = struct.Struct('<q')
double_lit = struct.Struct('<d')
float_lit = struct.Struct('<f')
u16_big = struct.Struct('>H')
s16_big = struct.Struct('>h')
u32_big = struct.Struct('>I')
s32_big = struct.Struct('>i')
u64_big = struct.Struct('>Q')
s64_big = struct.Struct('>q')
double_big = struct.Struct('>d')
float_big = struct.Struct('>f')

def get_dis_data_format1(src, data):
    out = ''
    for i in range(0, len(data)):
        if i % 16 == 0:
            if len(data) < i + 15:
                out += '[0x%08X~0x%08X]  ' % (int(src + i), int(src + i + 15))
            else:
                out += '[0x%08X~0x%08X]  ' % (int(src + i), int(src + i + 15))
        out += '%02X ' % data[i]

        if (i + 1) % 16 == 0:
            out += '\n'
    return out
    
def get_cfg_dict():
    try:
        cf = configparser.ConfigParser()
        cf.read('./cfg/parm.txt', encoding="utf-8-sig")
        ret = cf._sections
    except Exception as e:
        printf_except_info(e)
        return ret
    return ret


def get_cfg_other(name):
    cf = configparser.ConfigParser()
    cf.read('./cfg/parm.txt', encoding="utf-8-sig")

    if cf.has_section(name):
        return dict(cf.items(name))
    else:
        return None

def set_cfg(name, key, val):
    try:
        cf = configparser.ConfigParser()
        cf.read('./cfg/parm.txt', encoding="utf-8-sig")
        cf.set(name,key,value=str(val))
        with open('./cfg/parm.txt','w', encoding="utf-8-sig") as configration:
            cf.write(configration)
    except Exception as e:
        printf_except_info(e)

def get_map_info():
    name = get_cfg_other('MAP信息')
    ram_list = {}
    try:
        if 'path' in name:
            # print(name['path'])
            f = open(name['path'], 'r')
            msg = f.readlines()
            mark = 0

            for item in msg:
                if (('(.data)' in item) or ('.bss' in item)) and (' Data' in item):
                    temp = item.split()
                    ram_list[temp[0]] = [temp[1], temp[3]] 
    except Exception as e:
        printf_except_info(e)
    return ram_list

def get_cfg_keys():
    cf = configparser.ConfigParser()
    cf.read('./cfg/parm.txt', encoding="utf-8-sig")
    return cf.sections()

def Cal_crc8(ptr):
    crc = 0
    for i in range(0, len(ptr)):
        crc ^= ptr[i]
        for j in range(0, 8):
            if crc & 0x01:
                crc = (crc >> 1) ^ 0x8C
            else:
                crc >>= 1

    return crc & 0XFF

def get_hex_data(data):
    out = ''

    for item in data:
        out += '%02x ' % item
    return out

def get_time_str1():
    time_val = time.localtime()
    return '%04d/%02d/%02d %02d:%02d:%02d[%03d] ' % (
        time_val.tm_year, time_val.tm_mon, time_val.tm_mday, time_val.tm_hour, time_val.tm_min, time_val.tm_sec, time.time()*1000%1000)

def get_time_str():
    time_val = time.localtime()
    return '%d/%d/%d %d:%d:%d ' % (
        time_val.tm_year, time_val.tm_mon, time_val.tm_mday, time_val.tm_hour, time_val.tm_min, time_val.tm_sec)

def get_time1_str():
    time_val = time.localtime()
    return '%04d%02d%02d%02d%02d%02d' % (
        time_val.tm_year, time_val.tm_mon, time_val.tm_mday, time_val.tm_hour, time_val.tm_min, time_val.tm_sec)


def get_struct_size(structx):
    return len(bytearray(structx()) )
    
def get_timex_str(stm):
    time_val = time.localtime(stm)
    return '%04d/%02d/%02d %02d:%02d:%02d [%03d]' % (
        time_val.tm_year, time_val.tm_mon, time_val.tm_mday, time_val.tm_hour, time_val.tm_min, time_val.tm_sec,
        stm * 1000 % 1000)

log_cache = ''
g_pres_log = []

def write_log(data, cache=0,mode='now',line=sys._getframe().f_lineno,func=os.path.basename(sys._getframe().f_code.co_filename)):
    
    if mode == 'now':
        print('{} {}:{}  {}'.format(datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S'),func,line, data)) 
    else:
        global log_cache
        log_cache += (data + '\n')

        if len(log_cache) > 10240 or cache == 0:
            log_name = os.path.join(os.path.dirname(sys.argv[0]), datetime.datetime.now().strftime('%Y%m%d_%H.txt'))
            try:
                hd = open(log_name, 'a', encoding='utf-8')
                hd.write(str(log_cache))
                log_cache = ''
                hd.close()
            except Exception as e:
                print('{}:{} {} '.format(e.__traceback__.tb_frame.f_globals["__file__"], e.__traceback__.tb_lineno, e))

def write_pres_log(pres, cache=0):
    global g_pres_log
    g_pres_log.append((get_timex_str(time.time()),pres))

    if len(g_pres_log) > 30 :
        log_name = os.path.join(os.path.dirname(sys.argv[0]), datetime.datetime.now().strftime('PRES_LOG%Y%m%d_%H.txt'))
        try:
            hd = open(log_name, 'a', encoding='utf-8')
            for item in g_pres_log:
                hd.write('%s,%0.1f\n'%(item[0],item[1]))
            g_pres_log = []
            hd.close()
        except Exception as e:
            print('{}:{} {} '.format(e.__traceback__.tb_frame.f_globals["__file__"], e.__traceback__.tb_lineno, e))



def printf_except_info(e):
    msg = '{}:{} {} '.format(e.__traceback__.tb_frame.f_globals["__file__"], e.__traceback__.tb_lineno, e)
    # QMessageBox.information('错误',msg)
    print(msg)
    write_log(msg, cache=0)
    return msg

def get_dis_data(cfg, data, cntx):
    if 'type' in cfg.keys() and 'scale' in cfg.keys() and 'biglit' in cfg.keys():
        dis_msg = ''
        if cfg['type'] == 'u8':
            for i in range(0, len(data)):
                if cfg['scale'] == '16':
                    dis_msg += '%02X ' % data[i]
                elif cfg['scale'] == '10':
                    dis_msg += '%03d ' % data[i]
                elif cfg['scale'] == '2':
                    dis_msg += '{} '.format(bin(data[i]))
                if (i + 1) % cntx == 0:
                    dis_msg += '\n'
        elif cfg['type'] == 'u16':
            if len(data) % 2 != 0:
                return '长度错误'
            for i in range(0, int(len(data) / 2)):
                if cfg['scale'] == '16':
                    if cfg['biglit'] == 'big':
                        dis_msg += '%04X ' % (u16_big.unpack_from(data, i * 2)[0])
                    else:
                        dis_msg += '%04X ' % (u16_lit.unpack_from(data, i * 2)[0])
                elif cfg['scale'] == '10':
                    if cfg['biglit'] == 'big':
                        dis_msg += '%05d ' % (u16_big.unpack_from(data, i * 2)[0])
                    else:
                        dis_msg += '%05d ' % (u16_lit.unpack_from(data, i * 2)[0])
                elif cfg['scale'] == '2':
                    if cfg['biglit'] == 'big':
                        dis_msg += '{} '.format(bin(u16_big.unpack_from(data, i * 2)[0]))
                    else:
                        dis_msg += '{} '.format(bin(u16_big.unpack_from(data, i * 2)[0]))
                if (i + 1) % cntx == 0:
                    dis_msg += '\n'
            pass
        elif cfg['type'] == 'u32':
            if len(data) % 4 != 0:
                return '长度错误'
            for i in range(0, int(len(data) / 4)):
                if cfg['scale'] == '16':
                    if cfg['biglit'] == 'big':
                        dis_msg += '%08X ' % (u32_big.unpack_from(data, i * 4)[0])
                    else:
                        dis_msg += '%08X ' % (u32_lit.unpack_from(data, i * 4)[0])
                elif cfg['scale'] == '10':
                    if cfg['biglit'] == 'big':
                        dis_msg += '%010d ' % (u32_big.unpack_from(data, i * 4)[0])
                    else:
                        dis_msg += '%010d ' % (u32_lit.unpack_from(data, i * 4)[0])
                elif cfg['scale'] == '2':
                    if cfg['biglit'] == 'big':
                        dis_msg += '{} '.format(bin(u32_big.unpack_from(data, i * 4)[0]))
                    else:
                        dis_msg += '{} '.format(bin(u32_lit.unpack_from(data, i * 4)[0]))
                if (i + 1) % cntx == 0:
                    dis_msg += '\n'
            pass
        if len(dis_msg) > 0:
            if dis_msg[-1] != '\n':
                dis_msg += '\n'
        return dis_msg
    else:
        return ''